﻿using System;
using System.Collections.Generic;
using TrueSync;
using TrueSync.Physics2D;
using Framework;

public class AttackRectBase:Fixture
{
    //这个类是为了包装所有的攻击框体，因为可能会碰到好多对方的体位框
    Dictionary<int, Fixture> CollidingFixtures;

    public Action<List<Fixture>> OnCollisionCallback;

    public AttackRectBase(Shape shape, TSVector2 pos, FP rot, object userdata):base(shape, pos, rot, userdata)
    {
        CollidingFixtures = new Dictionary<int, Fixture>();
        OnCollision = DoOnCollisionCallback; 
    }

    void OnPreCollision()
    {
        CollidingFixtures.Clear();
    }

    public void OnPostCollision()
    {
        Dictionary<int, List<Fixture>> currentTouchingState = new Dictionary<int, List<Fixture>>();
        foreach(var item in CollidingFixtures.Values)
        {
            int entityID = ((ObjHandle<LogicEntity>)item.UserData).handle.EntityID;
            if (currentTouchingState.ContainsKey(entityID) == false)
            {
                currentTouchingState[entityID] = new List<Fixture>();
            }

            currentTouchingState[entityID].Add(item);
        }

        foreach(var item in currentTouchingState)
        {
            if (OnCollisionCallback != null)
                OnCollisionCallback(item.Value);
        }
    }

    public override void OnDestroy()
    {
        if (_world != null)
        {
            _world.OnPreCollision -= OnPreCollision;
            _world.OnPostCollision -= OnPostCollision;
        }

        OnCollisionCallback = null;

        base.OnDestroy();
    }

    void DoOnCollisionCallback(Fixture myFixture, Fixture otherFixture)
    {
        if (ShouldCollide(myFixture, otherFixture) == false)
            return;

        if (CollidingFixtures.ContainsKey(otherFixture.ID) == false)
            CollidingFixtures[otherFixture.ID] = otherFixture;
    }

    protected virtual bool ShouldCollide(Fixture myFixture, Fixture otherFixture)
    {
        ObjHandle<LogicEntity> myEntity = (ObjHandle<LogicEntity>)myFixture.UserData;
        ObjHandle<LogicEntity> otherEntity = (ObjHandle<LogicEntity>)otherFixture.UserData;
        //自己或者自己发出的东西过滤
        if (otherEntity.IsValid == false || otherEntity.handle.PlayerID == myEntity.handle.PlayerID)
            return false;

        return true;
    }

    public override void OnAddToWorld(CollisionWorld world)
    {
        base.OnAddToWorld(world);
        world.OnPreCollision += OnPreCollision;
        world.OnPostCollision += OnPostCollision;
    }

    public override void OnRemoveFromWorld(CollisionWorld world)
    {
        base.OnRemoveFromWorld(world);
        world.OnPreCollision -= OnPreCollision;
        world.OnPostCollision -= OnPostCollision;
    }
}

public class AttackRect : AttackRectBase
{
    public AttackRect(Shape shape, TSVector2 pos, FP rot, object userdata) : base(shape, pos, rot, userdata)
    {
        CollisionCategories = Category.Attack;
    }
}

public class FlySubitemAttackRect : AttackRectBase
{
    public FlySubitemAttackRect(Shape shape, TSVector2 pos, FP rot, object userdata) : base(shape, pos, rot, userdata)
    {
        CollisionCategories = Category.FlySubitemAttack;
    }
}


public class ThrowAttackRect : AttackRectBase
{
    public ThrowAttackRect(Shape shape, TSVector2 pos, FP rot, object userdata) : base(shape, pos, rot, userdata)
    {
        CollisionCategories = Category.Throw;
    }
}

public class StatusRect : AttackRectBase
{
    public StatusRect(Shape shape, TSVector2 pos, FP rot, object userdata) : base(shape, pos, rot, userdata)
    {
        CollisionCategories = Category.Status;
    }
}

public class CounterAttackRect : AttackRectBase
{
    public CounterAttackRect(Shape shape, TSVector2 pos, FP rot, object userdata) : base(shape, pos, rot, userdata)
    {
        CollisionCategories = Category.CounterAttack;
    }
}

public class CounterFlySubitemRect : AttackRectBase
{
    public CounterFlySubitemRect(Shape shape, TSVector2 pos, FP rot, object userdata) : base(shape, pos, rot, userdata)
    {
        CollisionCategories = Category.CounterFlySubitem;
    }
}
